using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectSelector : MonoBehaviour
{
    private GameObject selectedObject; // 当前选中的单个物体
    private List<GameObject> selectedObjects = new List<GameObject>(); // 存储多个选择的物体
    private Vector2 startMousePos; // 框选的起始位置
    private Vector2 endMousePos; // 框选的结束位置
    private bool isDragging = false; // 是否正在框选
    private bool isClicking = false; // 是否正在点击

    private float dragThreshold = 10f; // 拖动的阈值，单位：像素

    private List<GameObject> allObjects = new List<GameObject>(); // 保存所有物体

    private void Start()
    {
        // 在场景开始时获取所有物体
        allObjects.AddRange(GameObject.FindObjectsOfType<GameObject>());
    }

    private void Update()
    {
        CheckMouseInput();
    }

    private void CheckMouseInput()
    {
        // 检测鼠标左键按下（单击选择）
        if (Input.GetMouseButtonDown(0))
        {
            startMousePos = Input.mousePosition;
            isClicking = true; // 假设是点击
            isDragging = false; // 假设不是拖动
        }

        // 鼠标拖动过程中更新框选区域
        if (Input.GetMouseButton(0))
        {
            endMousePos = Input.mousePosition;
            CheckDragging();
        }

        // 鼠标左键释放，框选完成
        if (Input.GetMouseButtonUp(0))
        {
            HandleMouseRelease();
        }
    }

    private void CheckDragging()
    {
        // 计算鼠标当前位置与按下时的距离
        if (Vector2.Distance(startMousePos, endMousePos) > dragThreshold)
        {
            isDragging = true; // 距离超过阈值，认为是拖动
            isClicking = false; // 不再认为是点击
        }
    }

    private void HandleMouseRelease()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (isClicking)
        {
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                // 检测Ctrl或Shift键，判断是否多选
                if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftShift))
                {
                    ToggleSelection(hit.collider.gameObject); // 多选时切换选择状态
                }
                else
                {
                    SelectObject(hit.collider.gameObject); // 否则单独选择
                }
            }
            else
            {
                // 点击空白处取消选择
                DeselectAllObjects();
            }
        }
        else if (isDragging)
        {
            SelectObjectsInRect();
        }

        // 重置状态
        isClicking = false;
        isDragging = false;
    }

    // 单击选择物体
    private void SelectObject(GameObject obj)
    {
        DeselectAllObjects();
        selectedObject = obj;
        SetHighlight(selectedObject, true);
        selectedObjects.Add(selectedObject); // 新物体选择
    }

    // 多选：切换物体的选择状态
    private void ToggleSelection(GameObject obj)
    {
        if (selectedObjects.Contains(obj))
        {
            // 如果物体已经被选中，取消选择
            selectedObjects.Remove(obj);
            SetHighlight(obj, false);
        }
        else
        {
            // 否则添加到选择列表中
            selectedObjects.Add(obj);
            SetHighlight(obj, true);
        }
    }

    // 取消选择
    private void DeselectAllObjects()
    {
        foreach (var obj in selectedObjects)
        {
            SetHighlight(obj, false);
        }
        selectedObjects.Clear(); // 清空选择
    }

    // 框选范围内的物体
    private void SelectObjectsInRect()
    {
        Rect selectionRect = GetScreenRect(startMousePos, endMousePos);

        foreach (GameObject obj in allObjects)
        {
            Renderer renderer = obj.GetComponent<Renderer>();
            if (renderer != null)
            {
                Vector3 screenPos = Camera.main.WorldToScreenPoint(obj.transform.position);
                screenPos.y = Screen.height - screenPos.y; // Unity的屏幕坐标系y轴朝下，需要转换为常规坐标系y轴朝上
                if (selectionRect.Contains(screenPos, true))
                {
                    if (!selectedObjects.Contains(obj))
                    {
                        selectedObjects.Add(obj);
                        SetHighlight(obj, true);
                    }
                }
                else
                {
                    // 如果不在框选区域内且已经被选中，则取消选择
                    if (selectedObjects.Contains(obj))
                    {
                        selectedObjects.Remove(obj);
                        SetHighlight(obj, false);
                    }
                }
            }
        }
    }

    // 绘制框选矩形
    private void OnGUI()
    {
        if (isDragging)
        {
            Rect rect = GetScreenRect(startMousePos, endMousePos);
            DrawScreenRect(rect, new Color(0.8f, 0.8f, 1f, 0.25f)); // 半透明框
            DrawScreenRectBorder(rect, 2, Color.blue); // 蓝色边框
        }
    }

    // 设置物体高亮效果
    private void SetHighlight(GameObject obj, bool highlight)
    {
        Renderer renderer = obj.GetComponent<Renderer>();
        if (renderer != null)
        {
            renderer.material.color = highlight ? Color.yellow : Color.white; // 高亮为黄色
        }
    }

    // 获取屏幕坐标下的矩形
    private Rect GetScreenRect(Vector2 start, Vector2 end)
    {
        float left = Mathf.Min(start.x, end.x);
        float right = Mathf.Max(start.x, end.x);
        float top = Screen.height - Mathf.Max(start.y, end.y);
        float bottom = Screen.height - Mathf.Min(start.y, end.y);

        return Rect.MinMaxRect(left, top, right, bottom);
    }

    // 绘制矩形
    private void DrawScreenRect(Rect rect, Color color)
    {
        GUI.color = color;
        GUI.DrawTexture(rect, Texture2D.whiteTexture);
        GUI.color = Color.white;
    }

    // 绘制矩形边框
    private void DrawScreenRectBorder(Rect rect, float thickness, Color color)
    {
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color);
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color);
        DrawScreenRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color);
        DrawScreenRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color);
    }
}
